package com.tqyan.service.chat.impl.paper;

import com.alibaba.fastjson.JSONObject;
import com.tqyan.dal.mapper.PaperMapper;
import com.tqyan.model.controller.request.OpenAIChatMessageRequest;
import com.tqyan.model.controller.request.OpenAIChatRequest;
import com.tqyan.model.dto.*;
import com.tqyan.model.dto.paper.ChatOutlineDTO;
import com.tqyan.model.dto.paper.ConvertOutlineDTO;
import com.tqyan.model.dto.paper.OutlineDTO;
import com.tqyan.model.enums.PaperPayStatusEnum;
import com.tqyan.service.chat.AbstractChatPointService;
import com.tqyan.service.chat.ChatPointContent;
import com.tqyan.service.service.PaperService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * 聊天指令: 论文
 * <p> <功能详细描述> </p>
 *
 * @author 陈晨
 * @version 1.0
 * @date 2023/5/4
 */
@Service
@Slf4j
public class PaperChatPointService extends AbstractChatPointService {

    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private PaperService paperService;
    @Autowired
    private PaperViewChatPointService paperViewChatPointService;

    @Override
    public String getPoint() {
        return ChatPointContent.PAPER;
    }

    @Override
    public ChatContentDTO chatPoint(UserDTO user, UserSettingDTO userSetting, ChatDTO chat, String content) {
        // 查询用户未完成的论文
        PaperDTO paper = paperMapper.queryIncomplete(user.getId());
        if (null != paper) {
            String answerContent;
            if (PaperPayStatusEnum.PAID.getValue() == paper.getPayStatus()) {
                answerContent = String.format(ChatPointContent.ANSWER_1002, paper.getTitle());
            } else {
                answerContent = String.format(ChatPointContent.ANSWER_1003, paper.getTitle());
            }
            ChatContentDTO question = super.createQuestion(user, userSetting, chat, content, null, answerContent);
            ChatContentDTO answer = super.createAnswer(userSetting, question, answerContent);
            log.info("[{}] userId={}, paper={}, 取消论文, 对话入库", this.getPoint(), user.getId(), paper.getTitle());
            return answer;
        }
        // 获取论文标题
        content = content.replaceAll("：", ":");
        if (content.split(":").length < 2) {
            return null;
        }
        String title = content.split(":")[1].trim();
        // 记录对话
        ChatContentDTO question = super.createQuestion(user, userSetting, chat, content, null, null);
        ChatContentDTO answer = super.createAnswer(userSetting, question, null);
        // 请求问题, 答案流响应
        question.setContent(title);
        super.chatExecute(user, userSetting, chat, question, answer);
        return answer;
    }

    @Override
    protected void requestChatComplete(UserDTO user, UserSettingDTO userSetting, ChatDTO chat
            , ChatContentDTO question, ChatContentDTO completeAnswer) {
        // 更新回答字符数
        ChatContentDTO updateChatContent = new ChatContentDTO();
        updateChatContent.setId(question.getId());
        updateChatContent.setChatId(question.getChatId());
        updateChatContent.setOutputTokens(completeAnswer.getContent().length());
        chatContentMapper.update(updateChatContent);
//        log.info("[论文] userId={}, chatId={}, questionId={}, 更新会话内容tokens: {}", user.getId(), question.getChatId(), question.getId(), result);

        // 生成论文
        PaperDTO paper = this.generatePaper(user, question, completeAnswer);
        if (null == paper) {
            return;
        }
        // 生成返回结果
        String outline = paperViewChatPointService.generateOutline(paper);
        log.info("[论文] userId={}, title={}, 生成论文大纲: {}"
                , user.getId(), question.getContent(), outline);

        // 更新论文大纲
        updateChatContent = new ChatContentDTO();
        updateChatContent.setId(completeAnswer.getId());
        updateChatContent.setChatId(completeAnswer.getChatId());
        updateChatContent.setContent(outline);
        boolean result = chatContentMapper.update(updateChatContent) > 0;
        log.info("[论文] userId={}, chatId={}, answerId={}, 更新论文大纲: {}"
                , user.getId(), completeAnswer.getChatId(), completeAnswer.getId(), result);
    }

    @Override
    protected OpenAIChatRequest generateChatRequest(UserSettingDTO userSetting, ChatContentDTO question) {
        OpenAIChatRequest chatRequest = new OpenAIChatRequest();
        chatRequest.setModel(question.getGptModel());
        chatRequest.setTemperature(question.getTemperature() / 10D);
        OpenAIChatMessageRequest message = chatRequest.addMessage(question.getRole(), question.getContent());
        // 设置论文问题
        String content = "帮我写一篇关于“%s”的论文大纲，列出7个大标题，每个大标题分别再列出3个小标题";
        message.setContent(String.format(content, question.getContent()));
        log.info("[聊天] userId={}, chatId={}, chatRequest={}, 构建聊天请求"
                , question.getUserId(), question.getChatId(), chatRequest);
        return chatRequest;
    }

    /**
     * @description 生成论文
     * <p> <功能详细描述> </p>
     *
     * @author 陈晨
     * @date 2023/5/15 18:45
     */
    private PaperDTO generatePaper(UserDTO user, ChatContentDTO question, ChatContentDTO completeAnswer) {
        // 获取Chat回复大纲集合
        List<ChatOutlineDTO> chatOutlineList = ChatOutlineDTO.getOutlineList(completeAnswer.getContent());
        if (CollectionUtils.isEmpty(chatOutlineList)) {
            log.error("[论文] content={}, 非论文大纲", completeAnswer.getContent());
            return null;
        }
        // 转换Chat回复大纲
        List<ConvertOutlineDTO> convertOutlineList = ConvertOutlineDTO.convertChatOutline(chatOutlineList);
        // 处理大纲
        OutlineDTO outline = OutlineDTO.handleOutline(convertOutlineList);
        // 论文入库
        String outlineJSON = JSONObject.toJSONString(outline);
        PaperDTO paper = null;
        if (null != paperService) {
            paper = paperService.save(user.getId(), question.getContent(), outlineJSON);
        }
        log.info("[论文] userId={}, title={}, outline={}, 添加论文"
                , user.getId(), question.getContent(), outlineJSON);
        return paper;
    }

    public static void main(String[] args) {
        PaperChatPointService service = new PaperChatPointService();
        service.paperViewChatPointService = new PaperViewChatPointService();
        UserDTO user = new UserDTO();
        user.setId(1L);

        ChatContentDTO question = new ChatContentDTO();
        question.setContent("如何实现千万级企业应用");
        ChatContentDTO answer = new ChatContentDTO();
        answer.setContent("大标题1：技术实现\\n\\n小标题1：系统架构设计：\\n1. 分布式系统架构的设计与实现；\\n2. 基于微服务的架构设计与实现；\\n3. 大数据应用架构设计与实现。\\n\\n小标题2：技术选型：\\n1. 数据库技术的选择；\\n2. 缓存技术的选择；\\n3. 消息队列技术的选择。\\n\\n小标题3：代码质量：\\n1. 代码规范与统一性的保证；\\n2. 代码可维护性的提高；\\n3. 代码性能的优化。\\n\\n大标题2：业务流程设计\\n\\n小标题1：业务流程分析：\\n1. 业务场景的把握；\\n2. 业务流程的理解与分析；\\n3. 业务流程图的绘制与优化。\\n\\n小标题2：流程自动化：\\n1. 业务流程自动化的实现；\\n2. 流程引擎的选择与应用；\\n3. 常见自动化工具的使用。\\n\\n小标题3：架构优化：\\n1. 流程效率的提高；\\n2. 流程风险的降低；\\n3. 流程质量的提高。\\n\\n大标题3：数据管理\\n\\n小标题1：数据采集：\\n1. 数据源的选择与接入；\\n2. 数据质量的保证；\\n3. 数据采集的技术实现。\\n\\n小标题2：数据存储：\\n1. 数据库的选择与设计；\\n2. 数据的分区与分片；\\n3. 数据备份与恢复。\\n\\n小标题3：数据分析：\\n1. 数据分析技术的选择；\\n2. 数据分析模型的建立；\\n3. 数据分析结果的可视化。\\n\\n大标题4：项目管理\\n\\n小标题1：项目规划：\\n1. 项目目标的明确化；\\n2. 项目进程的规划与管理；\\n3. 项目资源的调配与管理。\\n\\n小标题2：团队建设：\\n1. 团队构成的明确化；\\n2. 团队角色的确定；\\n3. 团队协作能力的提高。\\n\\n小标题3：风险管理：\\n1. 风险评估与分类；\\n2. 风险管理与应对；\\n3. 风险管理工具的使用。\\n\\n大标题5：安全保障\\n\\n小标题1：安全意识：\\n1. 安全意识的提高与培训；\\n2. 安全责任的明确化与分工；\\n3. 安全制度的建立。\\n\\n小标题2：系统安全：\\n1. 系统漏洞的防范与监测；\\n2. 访问控制与权限管理；\\n3. 数据加密与解密。\\n\\n小标题3：数据备份与恢复：\\n1. 数据备份方案的设计与实现；\\n2. 数据恢复过程的规划与管理；\\n3. 数据备份防护策略的制定与落实。\n");
        service.generatePaper(user, question, answer);
        answer.setContent("大标题一：技术架构的优化\\n\\n小标题：\\n\\n1. 服务化架构的实现\\n2. 微服务架构的设计与应用\\n3. 大数据平台的构建\\n\\n大标题二：系统运维的优化\\n\\n小标题：\\n\\n1. 高可用的架构设计\\n2. 自动化运维的实现\\n3. 安全性的提升\\n\\n大标题三：开发方法的优化\\n\\n小标题：\\n\\n1. 领域驱动设计的运用\\n2. 敏捷开发的实践\\n3. DevOps的探讨\\n\\n大标题四：人才管理的优化\\n\\n小标题：\\n\\n1. 团队建设与管理\\n2. 绩效考核与激励机制的设计\\n3. 技术人员的培训与发展\\n\\n大标题五：项目管理的优化\\n\\n小标题：\\n\\n1. 项目管理的标准化与规范化\\n2. 项目进度的控制与风险管理\\n3. 项目质量的提升与保证\\n\\n以上是一份“如何实现千万级企业应用”的论文大纲，建议根据实际情况进行适当的调整和完善。\n");
        service.generatePaper(user, question, answer);
        answer.setContent("一、引言\\n- 选题背景\\n- 研究意义\\n- 研究目的\\n\\n二、千万级企业应用的特点\\n- 并发访问量高\\n- 数据处理量大\\n- 系统可靠性高\\n- 系统可扩展性强\\n- 系统安全性高\\n\\n三、千万级企业应用的架构设计\\n- 分布式架构\\n- 微服务架构\\n- 消息队列架构\\n\\n四、千万级企业应用的数据架构设计\\n- 数据分片\\n- 数据副本\\n- 数据备份与恢复\\n\\n五、千万级企业应用的性能优化\\n- 缓存优化\\n- 查询优化\\n- 网络优化\\n\\n六、总结\\n- 研究成果\\n- 未来展望\\n- 研究不足及改进方向\n");
        service.generatePaper(user, question, answer);
        answer.setContent("一、前言\\n  A.研究背景\\n  B.研究意义\\n  C.研究目的\\n\\n二、企业应用概述\\n  A.企业应用的特点\\n  B.企业应用的发展历程\\n  C.企业应用的分类\\n\\n三、实现千万级企业应用的关键技术\\n  A.分布式系统技术\\n    1.负载均衡技术\\n    2.容错机制技术\\n    3.数据分布技术\\n  B.大数据处理技术\\n    1.海量数据存储技术\\n    2.流式计算技术\\n    3.实时分析技术\\n  C.安全保障技术\\n    1.安全防御技术\\n    2.安全监控技术\\n    3.数据隐私保护技术\\n\\n四、实现千万级企业应用的实践案例\\n  A.金融行业\\n    1.企业级支付系统\\n    2.证券交易系统\\n    3.智能风控系统\\n  B.电商行业\\n    1.在线购物平台\\n    2.供应链管理系统\\n    3.客户关系管理系统\\n  C.物流行业\\n    1.全球配送系统\\n    2.智能仓储系统\\n    3.路线规划系统\\n\\n五、总结和展望\\n  A.论文总结\\n  B.存在问题及未来研究方向\\n  C.展望实现更高级别的企业应用的技术和发展趋势。\n");
        service.generatePaper(user, question, answer);
        answer.setContent("一、引言\\n1. 背景介绍 \\n2. 研究意义 \\n3. 论文框架 \\n\\n二、千万级企业应用的现状 \\n1. 前沿技术的应用 \\n2. 应用开发的挑战 \\n3. 相关案例分析 \\n\\n三、千万级企业应用的设计 \\n1. 架构设计 \\n2. 数据库设计 \\n3. 用户体验设计 \\n\\n四、千万级企业应用的实现 \\n1. 开发流程 \\n2. 技术选型 \\n3. 前端与后台开发的协同 \\n\\n五、千万级企业应用的测试与部署 \\n1. 测试策略 \\n2. 自动化测试 \\n3. 部署架构与流程 \\n\\n六、总结与展望 \\n1. 研究成果概括 \\n2. 研究局限与未来展望 \\n3. 后续工作建议 \\n\\n七、参考文献 \\n\\n注：以上只是一个论文大纲的提纲，实际写作时需根据具体情况进行拓展和深化。\n");
        service.generatePaper(user, question, answer);
        answer.setContent("大标题1：千万级企业应用的定义和挑战\\n\\n小标题1：千万级企业应用的定义和范围\\n小标题2：千万级企业应用面临的挑战和难点\\n小标题3：千万级企业应用不同于普通应用的特点和需求\\n\\n大标题2：千万级企业应用的技术实现\\n\\n小标题1：千万级企业应用的技术架构和架构设计\\n小标题2：千万级企业应用的技术选型和技术组合\\n小标题3：千万级企业应用的性能优化和容错机制设计\\n\\n大标题3：千万级企业应用的运维管理\\n\\n小标题1：千万级企业应用的运维管理模式和流程梳理\\n小标题2：千万级企业应用的运维管理工具和平台\\n小标题3：千万级企业应用的监控、诊断和反应机制设计\\n\\n大标题4：千万级企业应用的安全保障\\n\\n小标题1：千万级企业应用的安全风险评估和防范策略\\n小标题2：千万级企业应用的数据安全和网络安全保障\\n小标题3：千万级企业应用的合规性和安全审计机制\\n\\n大标题5：千万级企业应用的敏捷开发和协作研发\\n\\n小标题1：千万级企业应用的敏捷开发流程和方法\\n小标题2：千万级企业应用的跨团队协作和协作方式\\n小标题3：千万级企业应用的自动化测试和质量保证\\n\\n注：本篇大纲是根据用户提供的输入完成的，对于一些行业术语和细节处理可能存在不足。\n");
        service.generatePaper(user, question, answer);
        answer.setContent("大标题一：系统设计\\n1.需求分析\\n2.架构设计\\n3.数据库设计\\n\\n大标题二：软件开发\\n1.技术选型\\n2.编码规范\\n3.编码实践\\n\\n大标题三：系统测试\\n1.功能测试\\n2.压力测试\\n3.兼容性测试\\n\\n大标题四：上线之前\\n1.性能优化\\n2.系统安全\\n3.文档整理\\n\\n大标题五：生产上线\\n1.上线流程\\n2.事故预案\\n3.持续优化\n");
        service.generatePaper(user, question, answer);
        answer.setContent("一、引言\\n- 研究背景和意义\\n- 文章框架\\n- 论文所涉及企业应用简介\\n\\n二、企业应用开发流程\\n- 整体架构设计\\n- 数据库设计\\n- 编码实现\\n- 测试与部署\\n- 版本管理与维护\\n\\n三、性能优化与扩展\\n- 优化代码结构\\n- 使用跨平台技术\\n- 应用程序负载均衡\\n- 分布式应用程序部署\\n- 系统安全方案\\n\\n四、云计算与大数据\\n- 云计算系统架构\\n- 大数据处理技术\\n- 数据挖掘与分析\\n\\n五、人才培养与团队管理\\n- 技术培训与组织学习\\n- 分工合作与沟通管理\\n- 团队协作与文化建设\\n\\n六、总结与展望\\n- 本文研究成果\\n- 未来趋势和发展方向\\n- 存在的问题和解决方案\n");
        service.generatePaper(user, question, answer);
        answer.setContent("大标题一：技术选型\\n\\n小标题1：抉择最适合的开发语言\\n\\n小标题2：选择最合适的技术栈\\n\\n小标题3：核心技术的使用\\n\\n大标题二：架构设计\\n\\n小标题1：分布式系统设计\\n\\n小标题2：微服务架构的设计\\n\\n小标题3：数据治理的设计\\n\\n大标题三：系统优化\\n\\n小标题1：性能优化\\n\\n小标题2：安全优化\\n\\n小标题3：可靠性优化\\n\\n大标题四：组织建设\\n\\n小标题1：招聘最合适的人才\\n\\n小标题2：组建高效的开发团队\\n\\n小标题3：培训员工的技能\\n\\n大标题五：项目管理\\n\\n小标题1：选择最佳的开发模型\\n\\n小标题2：有效的需求管理\\n\\n小标题3：项目的跟踪和分析。");
        service.generatePaper(user, question, answer);

        question.setContent("决战紫禁之巅");
        answer.setContent("一、引言：介绍《决战紫禁之巅》的主题和意义\\n1. 选题背景与意义\\n2. 相关研究综述\\n3. 研究的目的和意义\\n\\n二、历史背景：元末明初的政治、军事、文化背景\\n1. 元朝灭亡的原因\\n2. 明朝建立的过程和原因\\n3. 明代的政治、军事、文化背景\\n\\n三、决战场景：分析紫禁之巅战役的决战场面\\n1. 紫禁城和城墙的特点\\n2. 明军和清军的兵力和装备\\n3. 战役期间的具体情况\\n\\n四、决战后果：分析紫禁之巅战役的影响和后果\\n1. 清朝建立的影响和意义\\n2. 明朝的衰落和灭亡\\n3. 现代史上的影响和启示\\n\\n五、结论：总结《决战紫禁之巅》的研究成果和价值\\n1. 研究发现和结论\\n2. 研究局限和不足\\n3. 研究展望和建议");
        service.generatePaper(user, question, answer);
        answer.setContent("论文大纲：《决战紫禁之巅》——对明清交替期的历史与文化意义分析\n" +
                "\n" +
                "I. 引言\n" +
                "A.研究背景和目的\n" +
                "B.研究方法和途径\n" +
                "C.研究价值和意义\n" +
                "\n" +
                "II. 明末的政治、经济和文化背景\n" +
                "A.明朝的衰落和朝廷的腐败\n" +
                "B.经济崩溃：盐法改革的失败和海禁政策\n" +
                "C.文化转型：洛阳文化之风和禅宗崛起\n" +
                "\n" +
                "III. 清朝的建立和发展\n" +
                "A.建立帝制：努尔哈赤统一后金和改号为清\n" +
                "B.政治体制改革：八旗军制度与三藩之乱\n" +
                "C.国家文化政策：儒学思想和考试制度的强化\n" +
                "\n" +
                "IV. 南明的衰落和降清的历史过程\n" +
                "A.藩镇割据和起义军的胜利\n" +
                "B.明末流亡文化的影响\n" +
                "C.明朝遗民和历史记忆\n" +
                "\n" +
                "V. “决战紫禁之巅”与文化意义\n" +
                "A.战役的背景和历史影响\n" +
                "B.文化符号的意义：“紫禁城”和“海瑞像”\n" +
                "C.文学艺术的表现：小说、戏曲与电影创作\n" +
                "\n" +
                "\n" +
                "VI. 结论\n" +
                "A.决战紫禁之巅的历史意义和历史评价\n" +
                "B.历史事件对今日社会的启示\n" +
                "C.继续深入研究的方向和方法\n" +
                "\n" +
                "\n" +
                "注：以上仅为一篇论文的大纲，实际写作应该根据研究内容和主题进行具体创作，增加必要的引用和证明");
        service.generatePaper(user, question, answer);
    }

}


